﻿using System;
using System.Collections.Generic;
using System.Globalization;

namespace NanoMvvm.Common
{
    public class ClockViewModel : PropertyObservableBase
    {
        private static readonly System.Timers.Timer timer;

        private static readonly List<ClockViewModel> instances;

        private static readonly object clockLock = new object();

        private string date;
        private int dayOfWeek;
        private string digitalTime;
        private string fullDateTime;
        private string fullDateTimeFormatString;
        private double hourAngle;
        private bool isRunning;
        private double minuteAngle;
        private double secondAngle;

        static ClockViewModel()
        {
            timer = new System.Timers.Timer(1000);
            instances = new List<ClockViewModel>();
            timer.Elapsed += TimerElapsed;
            timer.Start();
        }

        public string Date
        {
            get { return date; }
            private set { SetProperty(ref date, value, () => Date); }
        }

        public int DayOfWeek
        {
            get { return dayOfWeek; }
            private set { SetProperty(ref dayOfWeek, value, () => DayOfWeek); }
        }

        public string DigitalTime
        {
            get { return digitalTime; }
            private set { SetProperty(ref digitalTime, value, () => DigitalTime); }
        }

        public string FullDateTime
        {
            get { return fullDateTime; }
            private set { SetProperty(ref fullDateTime, value, () => FullDateTime); }
        }

        public string FullDateTimeFormatString
        {
            get { return fullDateTimeFormatString; }
            set { SetProperty(ref fullDateTimeFormatString, value, () => FullDateTimeFormatString); }
        }

        public double HourAngle
        {
            get { return hourAngle; }
            private set { SetProperty(ref hourAngle, value, () => HourAngle); }
        }

        public bool IsRunning
        {
            get { return isRunning; }
            private set { SetProperty(ref isRunning, value, () => IsRunning); }
        }

        public double MinuteAngle
        {
            get { return minuteAngle; }
            private set { SetProperty(ref minuteAngle, value, () => MinuteAngle); }
        }

        public double SecondAngle
        {
            get { return secondAngle; }
            private set { SetProperty(ref secondAngle, value, () => SecondAngle); }
        }

        public void Start()
        {
            if (!instances.Contains(this))
            {
                instances.Add(this);
            }

            IsRunning = true;
        }

        public void Stop()
        {
            instances.Remove(this);
            IsRunning = false;
        }

        private static void TimerElapsed(object sender, EventArgs e)
        {
            lock (clockLock)
            {
                DateTime now = DateTime.Now;

                var culture = NanoMvvmFramework.IsInitialized
                                  ? NanoMvvmFramework.Instance.Localization.CurrentUiCulture
                                  : CultureInfo.CurrentCulture;

                for (int i = 0; i < instances.Count; i++)
                {
                    var clockViewModel = instances[i];

                    clockViewModel.FullDateTime = string.IsNullOrEmpty(clockViewModel.FullDateTimeFormatString)
                                                      ? now.ToString(culture)
                                                      : now.ToString(clockViewModel.FullDateTimeFormatString, culture);
                    clockViewModel.DigitalTime = now.ToString("hh:mm:ss tt");
                    clockViewModel.SecondAngle = now.Second * 6;
                    clockViewModel.MinuteAngle = now.Minute * 6;
                    clockViewModel.HourAngle = (now.Hour * 30) + (now.Minute * 0.5);
                    clockViewModel.Date = now.ToString("DD.MM.YYYY.");
                    clockViewModel.DayOfWeek = (int)now.DayOfWeek;
                }
            }
        }
    }
}